﻿using System;
using System.Linq;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.DirectX.Direct3D;
using System.Threading;
using System.Collections.Generic;

namespace cz.zcu.PreSti.DirectX
{
    public class DirectXPresentation : Presentation
    {
        private Device display;
        private Sprite sprite;
        private object monitor = 1;

        public Device Display
        {
            get
            {
                return display;
            }
        }

        public Sprite Sprite
        {
            get
            {
                return sprite;
            }
        }

        public DirectXPresentation(Dictionary<string, ISymbols> symbols) : base(symbols) { }

        public void initDirectX(Control window, int width, int height, bool windowed)
        {
            PresentParameters param = new PresentParameters();
            param.BackBufferWidth = width;
            param.BackBufferHeight = height;
            param.BackBufferFormat = Format.R5G6B5;
            param.Windowed = windowed;
            param.SwapEffect = SwapEffect.Discard;
            display = new Device(0, DeviceType.Hardware, window, CreateFlags.SoftwareVertexProcessing, param);
            sprite = new Sprite(display);
        }

        public void draw()
        {
            Monitor.Enter(monitor);
            try
            {
                display.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
                display.BeginScene();
                sprite.Begin(SpriteFlags.AlphaBlend);
                RunnableComponent[] layers = new RunnableComponent[this.layers.Count()];
                this.layers.CopyTo(layers, 0, layers.Count());
                foreach (RunnableComponent l in layers)
                {
                    l.draw();
                }
                sprite.End();
                display.EndScene();
                display.Present();
            }
            catch (WasStillDrawingException)
            {
                return;
            }
            catch (NullReferenceException)
            {
                return;
            }
            finally
            {
                Monitor.Exit(monitor);
            }
        }
    }
}
